﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Notification;
using System.Diagnostics;
using System.Collections.ObjectModel;
using WP7Client.Helpers;
using WP7Client.ServerManager;
using System.IO;

namespace WP7Client.Managers
{
    public class NotificationManager
    {
        public event EventHandler NotificationReceived;

        protected void OnNotificationeceived(String message = null)
        {
            EventHandler handler = this.NotificationReceived;

            if (handler != null)
                handler(message, EventArgs.Empty);
        }

        private HttpNotificationChannel httpChannel;
        const String channelName = "MSHNotificationChannel";
        const int pushConnectTimeout = 30;

        public static NotificationManager current;

        public static NotificationManager Current
        {
            get { return current; }
            set { current = value; }
        }

        public void Connect()
        {
            try
            {
                httpChannel = HttpNotificationChannel.Find(channelName);

                if (null != httpChannel)
                {
                    SubscribeToChannelEvents();
                    SubscribeToService();
                    SubscribeToNotifications();
                    Deployment.Current.Dispatcher.BeginInvoke(() => this.UpdateStatus("Channel recovered"));
                }
                else
                {
                    httpChannel = new HttpNotificationChannel(channelName, "MSHNotificationChannel");
                    SubscribeToChannelEvents();
                    httpChannel.Open();
                    Deployment.Current.Dispatcher.BeginInvoke(() => this.UpdateStatus("Channel open requested"));
                }
            }
            catch (Exception ex)
            {
                Deployment.Current.Dispatcher.BeginInvoke(() => UpdateStatus("Channel error: " + ex.Message));
            }
        }

        private void SubscribeToService()
        {
            HttpGet subscribeHttpGet = new HttpGet(String.Format(GlobalHelper.Url + "WP7RegisterPushNotification/{0}/?uri={1}", UserHelper.Token, httpChannel.ChannelUri.ToString()), null);
        }

        private void SubscribeToChannelEvents()
        {
            httpChannel.ChannelUriUpdated += new EventHandler<NotificationChannelUriEventArgs>(httpChannel_ChannelUriUpdated);
            httpChannel.HttpNotificationReceived += new EventHandler<HttpNotificationEventArgs>(httpChannel_HttpNotificationReceived);
            httpChannel.ShellToastNotificationReceived += new EventHandler<NotificationEventArgs>(httpChannel_ShellToastNotificationReceived);
            httpChannel.ErrorOccurred += new EventHandler<NotificationChannelErrorEventArgs>(httpChannel_ErrorOccurred);
        }

        private void httpChannel_ErrorOccurred(object sender, NotificationChannelErrorEventArgs e)
        {
            Deployment.Current.Dispatcher.BeginInvoke(() => UpdateStatus(e.Message));
        }

        private void httpChannel_ShellToastNotificationReceived(object sender, NotificationEventArgs e)
        {
            Deployment.Current.Dispatcher.BeginInvoke(
                delegate {
                    String message1 = String.Empty;
                    String message2 = String.Empty;
                    e.Collection.TryGetValue("Text1", out message1);
                    e.Collection.TryGetValue("Text2", out message2);
                    
                    if(!String.IsNullOrEmpty(message2))
                        GlobalHelper.ShowMessage(message1, message2);
                    this.OnNotificationeceived();
                }
            );
        }

        private void httpChannel_ChannelUriUpdated(object sender, NotificationChannelUriEventArgs e)
        {
            SubscribeToService();
            SubscribeToNotifications();
            Deployment.Current.Dispatcher.BeginInvoke(() => UpdateStatus("Channel created successfully"));
        }

        private void httpChannel_HttpNotificationReceived(object sender, HttpNotificationEventArgs e)
        {
            String result = "";
            if (e != null && e.Notification != null && e.Notification.Body != null)
            {
                StreamReader reader = new StreamReader(e.Notification.Body);
                result = reader.ReadToEnd();
            }

            Deployment.Current.Dispatcher.BeginInvoke(
                delegate {
                    this.OnNotificationeceived(result);
                }
            );
        }

        private void SubscribeToNotifications()
        {
            try
            {
                if (httpChannel.IsShellToastBound != true)
                    httpChannel.BindToShellToast();
            }
            catch (Exception)
            {
            }

            try
            {
                if (httpChannel.IsShellTileBound != true)
                    httpChannel.BindToShellTile();
            }
            catch (Exception)
            {
            }
        }

        private void UpdateStatus(string message)
        {
            Debug.WriteLine(message);
        }

    }
}
